package com.bwie.service.impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.mapper.TbUserMapper;
import com.bwie.pojo.TbUser;
import com.bwie.service.TbUserService;
import com.bwie.utils.MobileMessageUtil;
import com.bwie.utils.R;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
@Log4j2
public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser> implements TbUserService {
    @Autowired
    TbUserMapper tbUserMapper;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Override
    public R sendCode(String mobile) {

        //校验手机号是否正确
        boolean b = Validator.isMobile(mobile);
        //生成随机的验证码
        String code = RandomUtil.randomNumbers(4);
        //发送成功后存到redis
        String key="CODE-"+mobile;

        String s = stringRedisTemplate.opsForValue().get(key);
        if (!StringUtils.isEmpty(s)) {
            return R.ERROR(500,"一分钟之内不能发送多次");
        }


        if (!b) {
            return R.ERROR(500,"手机号不正确,请重新输入");
        }


        //发送验证码
        Boolean aBoolean = MobileMessageUtil.sendMobileMessage(mobile, code);

        if (!aBoolean) {
            //发送失败，再次发送
            MobileMessageUtil.sendMobileMessage(mobile,code);
        }
        //一分钟后过期
        stringRedisTemplate.opsForValue().set(key,code,1, TimeUnit.MINUTES);

        return R.OK(code);
    }

    @Override
    public R userNameLogin(TbUser tbUser) {

        if (!StringUtils.isEmpty(tbUser.getCode())) {

            //查询手机号是否存在
            TbUser selectOne = tbUserMapper.selectOne(new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserMobile, tbUser.getUserMobile()));
            if (selectOne==null) {
                return R.ERROR(500,"手机号不存在");
            }
            //获取缓存中的验证码
            String key="CODE-"+tbUser.getUserMobile();
            String code = stringRedisTemplate.opsForValue().get(key);

            if (code==null) {
                return R.ERROR(500,"验证码不存在");
            }
            if (!tbUser.getCode().equals(code)) {
                return R.ERROR(500,"验证码不正确");
            }

            //生成Token
            String token = Jwts.builder().signWith(SignatureAlgorithm.HS256, "bwie")
                    .claim("id", selectOne.getUserId())
                    .claim("role", selectOne.getUserRole()).compact();

            //把token存到缓存中
            String tokenKey="TOKEN-"+selectOne.getUserId();
            stringRedisTemplate.opsForValue().set(tokenKey,token,30,TimeUnit.MINUTES);

            selectOne.setToken(token);
            return R.OK(selectOne);
        }else {
            if (StringUtils.isEmpty(tbUser.getUserName())) {
                return R.ERROR(500,"用户名不能为空");
            }
            if (StringUtils.isEmpty(tbUser.getUserPass())) {
                return R.ERROR(500,"密码不能为空");
            }
            //查询用户名是否正确
            TbUser one = tbUserMapper.selectOne(new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserName, tbUser.getUserName()));
            if (one==null) {
                return R.ERROR(500,"用户名不存在");
            }
            //判断密码是否正确
            String bcrypt = DigestUtil.bcrypt(tbUser.getUserPass());
            log.info("加密后的密码是"+bcrypt);

            boolean b = DigestUtil.bcryptCheck(tbUser.getUserPass(), one.getUserPass());
            if (!b) {
                return R.ERROR(500,"密码不正确,请输入正确的密码");
            }

            //生成token
            String token = Jwts.builder().signWith(SignatureAlgorithm.HS256, "bwie")
                    .claim("id", one.getUserId())
                    .claim("role", one.getUserRole()).compact();

            //把token存到缓存中
            String tokenKey="TOKEN-"+one.getUserId();
            stringRedisTemplate.opsForValue().set(tokenKey,token,30,TimeUnit.MINUTES);
            one.setUserPass(null);
            one.setToken(token);
            return R.OK(one);
        }
    }

    @Override
    public R retrieveUserPass(String mobile, String code, String userPass) {

        if (StringUtils.isEmpty(mobile)) {
            return R.ERROR(500,"手机号不能为空");
        }
        if (StringUtils.isEmpty(code)) {
            return R.ERROR(500,"验证码不能为空");
        }
        if (StringUtils.isEmpty(userPass)) {
            return R.ERROR(500,"新密码不能为空");
        }
        //校验手机号是否正确
        boolean b = Validator.isMobile(mobile);

        if (!b) {
            return R.ERROR(500,"手机号不正确");
        }
        String key="CODE-"+mobile;
        String redisCode = stringRedisTemplate.opsForValue().get(key);

        if (!code.equals(redisCode)) {
            return R.ERROR(500,"验证码不正确");
        }

        TbUser tbUser = tbUserMapper.selectOne(new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserMobile, mobile));

        if (tbUser==null) {
            return R.ERROR(500,"该手机号还未注册");
        }

        //密码加密存储
        String bcrypt = DigestUtil.bcrypt(userPass);
        tbUser.setUserPass(bcrypt);
        tbUserMapper.updateById(tbUser);
        return R.OK();
    }

    @Override
    public R TbUserList(String role) {

        List<TbUser> tbUsers = tbUserMapper.selectList(new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserRole, role));
        return R.OK(tbUsers);
    }
}
